#include <GSLAM/core/GSLAM.h>

using namespace sv;
using namespace std;

sv::Svar sockpp=GSLAM::Registry::load("svar_sockpp");

int main(int argc,char** argv){
    if(!sockpp.isObject())
        return -1;

    jvar.parseMain(argc,argv);

    bool server=jvar.arg("server",false,"As server mode or not");
    int  port  =jvar.arg("port",1025,"Tcp port");

    if(jvar.get("help",false)) return jvar.help();

    LOG(INFO)<<"Sockect initializing...";

    Svar init=sockpp["socket_initializer"]();
    LOG(INFO)<<"Sockect initialized.";

    if(server)
    {
        Svar s = sockpp["tcp_acceptor"](port);

        Svar socket=s.call("accept");

        if(!socket.call("is_connected").castAs<bool>())
        {
            cerr<<"Failed to connect."<<std::endl;
            return -2;
        }

        cout<<"Successfully connected by "<<socket.call("peer_address")<<std::endl;

        SvarBuffer buf(256);

        while(socket.call("is_connected").castAs<bool>()){
            int received=socket.call("read",buf).castAs<int>();

            if(received > 0){
                cout<< "received:" << std::string((char*)buf.ptr(),received) <<std::endl;

                std::string r("received:");
                r+=std::string((char*)buf.ptr(),received);
                socket.call("write",SvarBuffer(r.data(),r.size()));
            }
            else if(!socket.call("is_connected").castAs<bool>()){
                cout<<socket.call("peer_address")<<"Disconnected."<<endl;
                return 0;
            }
        }
    }
    else{
        Svar s = sockpp["tcp_connector"]("localhost",port);

        if(!s.call("is_connected").as<bool>()){
            cout<<"Failed to connect.";
            return -3;
        }

        cout<<"Please type the content you wanna send:"<<std::endl;

        while(true){
            std::string line;
            std::getline(cin,line);
            if(s.call("write",SvarBuffer(line.data(),line.size()))!=(int)line.size())
            {
                cout<<s.call("last_error_str")<<endl;
            }

            sv::SvarBuffer buf(1024);
            int received=s.call("read",buf).as<int>();

            cout<<std::string((char*)buf.ptr(),received)<<endl;
        }
    }

    return 0;
}
